/*
 * Copyright (c) Huawei Device Co., Ltd. 2023. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "arf_manager.h"

#include <gtest/gtest.h>
#include <memory>

#include "channel.h"
#include "ipc_object_stub.h"
#include "loghelper.h"
#include "reader.h"
#include "se_service.h"
#include "service_manager.h"
#include "access_control_enforcer.h"
#include "secure_element_agent.h"
#include "access_rule_cache.h"
#include "access_rule_driver.h"
#include "ara_controller.h"
#include "ef_parser.h"

namespace OHOS {
namespace SE {
namespace TEST {
using namespace testing::ext;
using namespace OHOS::SE;
using namespace OHOS::SE::OMAPI;

class ArfManagerTest : public testing::Test {
public:
    static void SetUpTestCase() {};
    static void TearDownTestCase() {};
    void SetUp();
    void TearDown();
};

class ISecureElementChannelImpl : public ISecureElementChannel {
public:
    ISecureElementChannelImpl() {}

    virtual ~ISecureElementChannelImpl() {}

public:
    ErrorCode Transmit(const std::string &command, std::string& response) override
    {
        response = "0000";
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode Close(void) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsClosed(bool &isClosed) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsBasicChannel(bool &isBasicChannel) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetSelectResponse(std::string &selectResponse) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode SelectNext(bool &selectStatus) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetChannelNumber(uint8_t &channelNumber) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    OHOS::sptr<OHOS::IRemoteObject> AsObject() override
    {
        return nullptr;
    }
};

class ISecureElementChannelImpl1 : public ISecureElementChannel {
public:
    ISecureElementChannelImpl1() {}

    virtual ~ISecureElementChannelImpl1() {}

public:
    ErrorCode Transmit(const std::string &command, std::string& response) override
    {
        response = "00000000000000";
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode Close(void) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsClosed(bool &isClosed) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsBasicChannel(bool &isBasicChannel) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetSelectResponse(std::string &selectResponse) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode SelectNext(bool &selectStatus) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetChannelNumber(uint8_t &channelNumber) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    OHOS::sptr<OHOS::IRemoteObject> AsObject() override
    {
        return nullptr;
    }
};

class ISecureElementChannelImpl2 : public ISecureElementChannel {
public:
    ISecureElementChannelImpl2() {}

    virtual ~ISecureElementChannelImpl2() {}

public:
    ErrorCode Transmit(const std::string &command, std::string& response) override
    {
        return ErrorCode::SE_ILLEGAL_STATE_ERROR;
    }

    ErrorCode Close(void) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsClosed(bool &isClosed) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsBasicChannel(bool &isBasicChannel) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetSelectResponse(std::string &selectResponse) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode SelectNext(bool &selectStatus) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetChannelNumber(uint8_t &channelNumber) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    OHOS::sptr<OHOS::IRemoteObject> AsObject() override
    {
        return nullptr;
    }
};

class ISecureElementChannelImpl3 : public ISecureElementChannel {
public:
    ISecureElementChannelImpl3() {}

    virtual ~ISecureElementChannelImpl3() {}

public:
    ErrorCode Transmit(const std::string &command, std::string& response) override
    {
        response = "00";
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode Close(void) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsClosed(bool &isClosed) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode IsBasicChannel(bool &isBasicChannel) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetSelectResponse(std::string &selectResponse) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode SelectNext(bool &selectStatus) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    ErrorCode GetChannelNumber(uint8_t &channelNumber) override
    {
        return ErrorCode::SE_SUCCESS;
    }

    OHOS::sptr<OHOS::IRemoteObject> AsObject() override
    {
        return nullptr;
    }
};

void ArfManagerTest::SetUp()
{
}

void ArfManagerTest::TearDown()
{
}

std::string g_arfManagerTestErrorLog;
void ArfManagerTestLogCallback(
    const LogType type, const LogLevel level, const unsigned int domain, const char *tag, const char *msg)
{
    g_arfManagerTestErrorLog = msg;
}

/**
 * @tc.name: Initialize_Test001
 * @tc.desc: Test Initialize.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, Initialize_Test001, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    bool ret = ArfManager::GetInstance().Initialize(seAgent);
    EXPECT_TRUE(!ret);
}

/**
 * @tc.name: Initialize_Test002
 * @tc.desc: Test Initialize.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, Initialize_Test002, TestSize.Level1)
{
    std::shared_ptr<SecureElementAgent> seAgent = std::make_shared<SecureElementAgent>("");
    bool ret = ArfManager::GetInstance().Initialize(seAgent);
    EXPECT_TRUE(!ret);
}

/**
 * @tc.name: Initialize_Test003
 * @tc.desc: Test Initialize.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, Initialize_Test003, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    ArfManager::GetInstance().Initialize(seAgent);
    bool ret = ArfManager::GetInstance().Initialize(seAgent);
    EXPECT_TRUE(!ret);
}

/**
 * @tc.name: ReadRefreshTag_Test001
 * @tc.desc: Test ReadRefreshTag.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, ReadRefreshTag_Test001, TestSize.Level1)
{
    sptr<ISecureElementChannelImpl> iSecureElementChannelImpl =
        sptr<ISecureElementChannelImpl>(new (std::nothrow) ISecureElementChannelImpl());
    std::vector<uint8_t> retRefreshTag= {0x01, 0x02, 0x03};
    std::shared_ptr<AccessRuleDriver> accessRuleDriver = std::make_shared<AccessRuleDriver>(iSecureElementChannelImpl);
    int ret = accessRuleDriver->ReadRefreshTag(retRefreshTag);
    EXPECT_TRUE(ret == BER_RET_HEADER_ERROR);
}

/**
 * @tc.name: ReadRefreshTag_Test002
 * @tc.desc: Test ReadRefreshTag.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, ReadRefreshTag_Test002, TestSize.Level1)
{
    sptr<ISecureElementChannelImpl1> iSecureElementChannelImpl =
        sptr<ISecureElementChannelImpl1>(new (std::nothrow) ISecureElementChannelImpl1());
    std::vector<uint8_t> retRefreshTag= {0x01, 0x02, 0x03};
    std::shared_ptr<AccessRuleDriver> accessRuleDriver = std::make_shared<AccessRuleDriver>(iSecureElementChannelImpl);
    int ret = accessRuleDriver->ReadRefreshTag(retRefreshTag);
    EXPECT_TRUE(ret == BER_RET_HEADER_ERROR);
}

/**
 * @tc.name: ReadRefreshTag_Test003
 * @tc.desc: Test ReadRefreshTag.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, ReadRefreshTag_Test003, TestSize.Level1)
{
    sptr<ISecureElementChannelImpl2> iSecureElementChannelImpl =
        sptr<ISecureElementChannelImpl2>(new (std::nothrow) ISecureElementChannelImpl2());
    std::vector<uint8_t> retRefreshTag= {0x01, 0x02, 0x03};
    std::shared_ptr<AccessRuleDriver> accessRuleDriver = std::make_shared<AccessRuleDriver>(iSecureElementChannelImpl);
    int ret = accessRuleDriver->ReadRefreshTag(retRefreshTag);
    EXPECT_TRUE(ret == static_cast<int>(ErrorCode::SE_ILLEGAL_STATE_ERROR));
}

/**
 * @tc.name: ReadAllAccessRules_Test001
 * @tc.desc: Test ReadAllAccessRules.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, ReadAllAccessRules_Test001, TestSize.Level1)
{
    sptr<ISecureElementChannelImpl2> iSecureElementChannelImpl =
        sptr<ISecureElementChannelImpl2>(new (std::nothrow) ISecureElementChannelImpl2());
    std::vector<uint8_t> accessRules;
    std::shared_ptr<AccessRuleDriver> accessRuleDriver = std::make_shared<AccessRuleDriver>(iSecureElementChannelImpl);
    int ret = accessRuleDriver->ReadAllAccessRules(accessRules);
    EXPECT_TRUE(ret == static_cast<int>(ErrorCode::SE_ILLEGAL_STATE_ERROR));
}

/**
 * @tc.name: ReadAllAccessRules_Test002
 * @tc.desc: Test ReadAllAccessRules.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, ReadAllAccessRules_Test002, TestSize.Level1)
{
    sptr<ISecureElementChannelImpl3> iSecureElementChannelImpl =
        sptr<ISecureElementChannelImpl3>(new (std::nothrow) ISecureElementChannelImpl3());
    std::vector<uint8_t> accessRules;
    std::shared_ptr<AccessRuleDriver> accessRuleDriver = std::make_shared<AccessRuleDriver>(iSecureElementChannelImpl);
    int ret = accessRuleDriver->ReadAllAccessRules(accessRules);
    EXPECT_TRUE(ret == -1);
}

/**
 * @tc.name: ReadAllAccessRules_Test003
 * @tc.desc: Test ReadAllAccessRules.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, ReadAllAccessRules_Test003, TestSize.Level1)
{
    sptr<ISecureElementChannelImpl> iSecureElementChannelImpl =
        sptr<ISecureElementChannelImpl>(new (std::nothrow) ISecureElementChannelImpl());
    std::vector<uint8_t> accessRules;
    std::shared_ptr<AccessRuleDriver> accessRuleDriver = std::make_shared<AccessRuleDriver>(iSecureElementChannelImpl);
    int ret = accessRuleDriver->ReadAllAccessRules(accessRules);
    EXPECT_TRUE(ret == -1);
}

/**
 * @tc.name: TransmitArfApdu_Test001
 * @tc.desc: Test TransmitArfApdu.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, TransmitArfApdu_Test001, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    std::vector<uint8_t> cmd;
    ArfManager::GetInstance().Initialize(seAgent);
    std::shared_ptr<EfParser> ef = std::make_shared<EfParser>();
    ArfManager::GetInstance().SetUsedSeName(SE_NAME_SIM);
    std::vector<uint8_t> ret = ArfManager::GetInstance().TransmitArfApdu(ef, cmd);
    EXPECT_TRUE(ret.size() == 0);
}

/**
 * @tc.name: TransmitArfApdu_Test002
 * @tc.desc: Test TransmitArfApdu.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, TransmitArfApdu_Test002, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    std::vector<uint8_t> cmd = {0x01, 0x02, 0x03, 0x03, 0x04, 0x05};
    ArfManager::GetInstance().Initialize(seAgent);
    std::shared_ptr<EfParser> ef = std::make_shared<EfParser>();
    ArfManager::GetInstance().SetUsedSeName(SE_NAME_SIM);
    std::vector<uint8_t> ret = ArfManager::GetInstance().TransmitArfApdu(ef, cmd);
    EXPECT_TRUE(ret.size() == 0);
}

/**
 * @tc.name: TransmitArfApdu_Test003
 * @tc.desc: Test TransmitArfApdu.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, TransmitArfApdu_Test003, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    std::vector<uint8_t> cmd = {0x01, 0x02, 0x03, 0x03, 0x04, 0x05};
    std::vector<uint8_t> path = {0x00, 0x48, 0x01, 0x02};
    ArfManager::GetInstance().Initialize(seAgent);
    std::shared_ptr<EfParser> ef = std::make_shared<EfParser>();
    ArfManager::GetInstance().SetUsedSeName(SE_NAME_SIM);
    uint16_t rspApdu = 0;
    ef->ReadFileByPath(path, rspApdu);
    std::vector<uint8_t> ret = ArfManager::GetInstance().TransmitArfApdu(ef, cmd);
    EXPECT_TRUE(ret.size() == 0);
}

/**
 * @tc.name: TransmitArfApdu_Test004
 * @tc.desc: Test TransmitArfApdu.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, TransmitArfApdu_Test004, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    std::vector<uint8_t> cmd = {0x01, 0xB0, 0x03, 0x03, 0x04, 0x05};
    std::vector<uint8_t> path = {0x00, 0x48, 0x01, 0x02};
    ArfManager::GetInstance().Initialize(seAgent);
    std::shared_ptr<EfParser> ef = std::make_shared<EfParser>();
    ArfManager::GetInstance().SetUsedSeName(SE_NAME_SIM);
    uint16_t rspApdu = 0;
    ef->ReadFileByPath(path, rspApdu);
    std::vector<uint8_t> ret = ArfManager::GetInstance().TransmitArfApdu(ef, cmd);
    EXPECT_TRUE(ret.size() == 0);
}

/**
 * @tc.name: TransmitArfApdu_Test005
 * @tc.desc: Test TransmitArfApdu.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, TransmitArfApdu_Test005, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    std::vector<uint8_t> cmd = {0x01, 0xB2, 0x03, 0x03, 0x04, 0x05};
    std::vector<uint8_t> path = {0x00, 0x48, 0x01, 0x02};
    ArfManager::GetInstance().Initialize(seAgent);
    std::shared_ptr<EfParser> ef = std::make_shared<EfParser>();
    ArfManager::GetInstance().SetUsedSeName(SE_NAME_SIM);
    uint16_t rspApdu = 0;
    ef->ReadFileByPath(path, rspApdu);
    std::vector<uint8_t> ret = ArfManager::GetInstance().TransmitArfApdu(ef, cmd);
    EXPECT_TRUE(ret.size() == 0);
}

/**
 * @tc.name: TransmitArfApdu_Test006
 * @tc.desc: Test TransmitArfApdu.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, TransmitArfApdu_Test006, TestSize.Level1)
{
    std::weak_ptr<SecureElementAgent> seAgent;
    std::vector<uint8_t> cmd = {0x01, 0xA4, 0x03, 0x03, 0x04, 0x05};
    std::vector<uint8_t> path = {0x00, 0x48, 0x01, 0x02};
    ArfManager::GetInstance().Initialize(seAgent);
    std::shared_ptr<EfParser> ef = std::make_shared<EfParser>();
    ArfManager::GetInstance().SetUsedSeName(SE_NAME_SIM);
    uint16_t rspApdu = 0;
    ef->ReadFileByPath(path, rspApdu);
    std::vector<uint8_t> ret = ArfManager::GetInstance().TransmitArfApdu(ef, cmd);
    EXPECT_TRUE(ret.size() == 0);
}

/**
 * @tc.name: AddArfRule_Test001
 * @tc.desc: Test AddArfRule.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, AddArfRule_Test001, TestSize.Level1)
{
    LOG_SetCallback(ArfManagerTestLogCallback);
    std::shared_ptr<SecureElementAgent> seAgent = std::make_shared<SecureElementAgent>("");
    shared_ptr<AidRefDo> aidRefDo = nullptr;
    std::shared_ptr<DeviceAppIdRefDo> deviceAppIdRefDo = nullptr;
    bool isAllowed = false;
    ArfManager::GetInstance().Initialize(seAgent);
    ArfManager::GetInstance().AddArfRule(aidRefDo, deviceAppIdRefDo, isAllowed);
    EXPECT_TRUE(g_arfManagerTestErrorLog.find("seAgent expired") == std::string::npos);
}


/**
 * @tc.name: AddArfRule_Test002
 * @tc.desc: Test AddArfRule.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, AddArfRule_Test002, TestSize.Level1)
{
    LOG_SetCallback(ArfManagerTestLogCallback);
    std::shared_ptr<SecureElementAgent> seAgent = std::make_shared<SecureElementAgent>("");
    std::vector<uint8_t> payload;
    bool isPayload = false;
    uint32_t tag = 0;
    shared_ptr<AidRefDo> aidRefDo = std::make_shared<AidRefDo>(payload, isPayload, tag);
    std::shared_ptr<DeviceAppIdRefDo> deviceAppIdRefDo = nullptr;
    bool isAllowed = false;
    ArfManager::GetInstance().Initialize(seAgent);
    ArfManager::GetInstance().AddArfRule(aidRefDo, deviceAppIdRefDo, isAllowed);
    EXPECT_TRUE(g_arfManagerTestErrorLog.find("seAgent expired") == std::string::npos);
}

/**
 * @tc.name: AddArfRule_Test003
 * @tc.desc: Test AddArfRule.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, AddArfRule_Test003, TestSize.Level1)
{
    LOG_SetCallback(ArfManagerTestLogCallback);
    std::shared_ptr<SecureElementAgent> seAgent = std::make_shared<SecureElementAgent>("");
    std::vector<uint8_t> rawData;
    shared_ptr<AidRefDo> aidRefDo = nullptr;
    std::shared_ptr<DeviceAppIdRefDo> deviceAppIdRefDo = std::make_shared<DeviceAppIdRefDo>(rawData);
    bool isAllowed = false;
    ArfManager::GetInstance().Initialize(seAgent);
    ArfManager::GetInstance().AddArfRule(aidRefDo, deviceAppIdRefDo, isAllowed);
    EXPECT_TRUE(g_arfManagerTestErrorLog.find("seAgent expired") == std::string::npos);
}

/**
 * @tc.name: AddArfRule_Test004
 * @tc.desc: Test AddArfRule.
 * @tc.type: FUNC
 */
HWTEST_F(ArfManagerTest, AddArfRule_Test004, TestSize.Level1)
{
    LOG_SetCallback(ArfManagerTestLogCallback);
    std::shared_ptr<SecureElementAgent> seAgent = std::make_shared<SecureElementAgent>("");
    std::vector<uint8_t> rawData;
    std::vector<uint8_t> payload;
    bool isPayload = false;
    uint32_t tag = 0;
    shared_ptr<AidRefDo> aidRefDo = std::make_shared<AidRefDo>(payload, isPayload, tag);
    std::shared_ptr<DeviceAppIdRefDo> deviceAppIdRefDo = std::make_shared<DeviceAppIdRefDo>(rawData);
    bool isAllowed = false;
    ArfManager::GetInstance().Initialize(seAgent);
    ArfManager::GetInstance().AddArfRule(aidRefDo, deviceAppIdRefDo, isAllowed);
    EXPECT_TRUE(g_arfManagerTestErrorLog.find("seAgent expired") == std::string::npos);
}
} // TEST
} // SE
} // OHOS